/*
 * e9tool.h
 * Copyright (C) 2023 National University of Singapore
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __E9TOOL_H
#define __E9TOOL_H

#include <map>
#include <vector>

#include <cstdint>
#include <cstdio>
#include <cstring>

#include <elf.h>

#define NO_RETURN       __attribute__((__noreturn__))

#define MAX_ARGNO       8

namespace e9tool
{

/*
 * C-string comparator.
 */
struct CStrCmp
{
    bool operator()(const char *a, const char *b) const
    {
        return (strcmp(a, b) < 0);
    }
};

/*
 * ELF Types.
 */
typedef std::map<const char *, const Elf64_Shdr *, CStrCmp> SectionInfo;
typedef std::map<const char *, const Elf64_Sym *, CStrCmp>  SymbolInfo;
typedef std::map<const char *, intptr_t, CStrCmp> GOTInfo;
typedef std::map<const char *, intptr_t, CStrCmp> PLTInfo;

/*
 * Binary file type.
 */
enum BinaryType
{
    BINARY_TYPE_ELF_DSO,            // Linux ELF Shared object
    BINARY_TYPE_ELF_PIE,            // Linux ELF PIE Executable
    BINARY_TYPE_ELF_EXE,            // Linux ELF non-PIE Executable
    BINARY_TYPE_PE_DLL,             // Windows PE DLL
    BINARY_TYPE_PE_EXE,             // Windows PE Executable
};
struct ELF;

/*
 * Patch pos.
 */
enum PatchPos
{
    POS_BEFORE,                     // Instrument before
    POS_REPLACE,                    // Replace instruction
    POS_AFTER,                      // Instrument after
};

/*
 * Call ABI.
 */
enum CallABI
{
    ABI_CLEAN,                      // Clean ABI
    ABI_NAKED,                      // Naked ABI
};

/*
 * Jump kind
 */
enum CallJump
{
    JUMP_NONE,
    JUMP_BREAK,                     // if (f(...) != 0) break; ...
    JUMP_GOTO,                      // if (addr = f(...)) goto addr; ...
};

/*
 * Mnemonics.
 */
enum Mnemonic : int16_t
{
    MNEMONIC_AAA,
    MNEMONIC_AAD,
    MNEMONIC_AAM,
    MNEMONIC_AAS,
    MNEMONIC_ADC,
    MNEMONIC_ADCX,
    MNEMONIC_ADD,
    MNEMONIC_ADDPD,
    MNEMONIC_ADDPS,
    MNEMONIC_ADDSD,
    MNEMONIC_ADDSS,
    MNEMONIC_ADDSUBPD,
    MNEMONIC_ADDSUBPS,
    MNEMONIC_ADOX,
    MNEMONIC_AESDEC,
    MNEMONIC_AESDECLAST,
    MNEMONIC_AESENC,
    MNEMONIC_AESENCLAST,
    MNEMONIC_AESIMC,
    MNEMONIC_AESKEYGENASSIST,
    MNEMONIC_AND,
    MNEMONIC_ANDN,
    MNEMONIC_ANDNPD,
    MNEMONIC_ANDNPS,
    MNEMONIC_ANDPD,
    MNEMONIC_ANDPS,
    MNEMONIC_ARPL,
    MNEMONIC_BEXTR,
    MNEMONIC_BLCFILL,
    MNEMONIC_BLCI,
    MNEMONIC_BLCIC,
    MNEMONIC_BLCMSK,
    MNEMONIC_BLCS,
    MNEMONIC_BLENDPD,
    MNEMONIC_BLENDPS,
    MNEMONIC_BLENDVPD,
    MNEMONIC_BLENDVPS,
    MNEMONIC_BLSFILL,
    MNEMONIC_BLSI,
    MNEMONIC_BLSIC,
    MNEMONIC_BLSMSK,
    MNEMONIC_BLSR,
    MNEMONIC_BNDCL,
    MNEMONIC_BNDCN,
    MNEMONIC_BNDCU,
    MNEMONIC_BNDLDX,
    MNEMONIC_BNDMK,
    MNEMONIC_BNDMOV,
    MNEMONIC_BNDSTX,
    MNEMONIC_BOUND,
    MNEMONIC_BSF,
    MNEMONIC_BSR,
    MNEMONIC_BSWAP,
    MNEMONIC_BT,
    MNEMONIC_BTC,
    MNEMONIC_BTR,
    MNEMONIC_BTS,
    MNEMONIC_BZHI,
    MNEMONIC_CALL,
    MNEMONIC_CBW,
    MNEMONIC_CDQ,
    MNEMONIC_CDQE,
    MNEMONIC_CLAC,
    MNEMONIC_CLC,
    MNEMONIC_CLD,
    MNEMONIC_CLDEMOTE,
    MNEMONIC_CLEVICT0,
    MNEMONIC_CLEVICT1,
    MNEMONIC_CLFLUSH,
    MNEMONIC_CLFLUSHOPT,
    MNEMONIC_CLGI,
    MNEMONIC_CLI,
    MNEMONIC_CLRSSBSY,
    MNEMONIC_CLTS,
    MNEMONIC_CLWB,
    MNEMONIC_CLZERO,
    MNEMONIC_CMC,
    MNEMONIC_CMOVB,
    MNEMONIC_CMOVBE,
    MNEMONIC_CMOVL,
    MNEMONIC_CMOVLE,
    MNEMONIC_CMOVNB,
    MNEMONIC_CMOVNBE,
    MNEMONIC_CMOVNL,
    MNEMONIC_CMOVNLE,
    MNEMONIC_CMOVNO,
    MNEMONIC_CMOVNP,
    MNEMONIC_CMOVNS,
    MNEMONIC_CMOVNZ,
    MNEMONIC_CMOVO,
    MNEMONIC_CMOVP,
    MNEMONIC_CMOVS,
    MNEMONIC_CMOVZ,
    MNEMONIC_CMP,
    MNEMONIC_CMPPD,
    MNEMONIC_CMPPS,
    MNEMONIC_CMPSB,
    MNEMONIC_CMPSD,
    MNEMONIC_CMPSQ,
    MNEMONIC_CMPSS,
    MNEMONIC_CMPSW,
    MNEMONIC_CMPXCHG,
    MNEMONIC_CMPXCHG16B,
    MNEMONIC_CMPXCHG8B,
    MNEMONIC_COMISD,
    MNEMONIC_COMISS,
    MNEMONIC_CPUID,
    MNEMONIC_CQO,
    MNEMONIC_CRC32,
    MNEMONIC_CVTDQ2PD,
    MNEMONIC_CVTDQ2PS,
    MNEMONIC_CVTPD2DQ,
    MNEMONIC_CVTPD2PI,
    MNEMONIC_CVTPD2PS,
    MNEMONIC_CVTPI2PD,
    MNEMONIC_CVTPI2PS,
    MNEMONIC_CVTPS2DQ,
    MNEMONIC_CVTPS2PD,
    MNEMONIC_CVTPS2PI,
    MNEMONIC_CVTSD2SI,
    MNEMONIC_CVTSD2SS,
    MNEMONIC_CVTSI2SD,
    MNEMONIC_CVTSI2SS,
    MNEMONIC_CVTSS2SD,
    MNEMONIC_CVTSS2SI,
    MNEMONIC_CVTTPD2DQ,
    MNEMONIC_CVTTPD2PI,
    MNEMONIC_CVTTPS2DQ,
    MNEMONIC_CVTTPS2PI,
    MNEMONIC_CVTTSD2SI,
    MNEMONIC_CVTTSS2SI,
    MNEMONIC_CWD,
    MNEMONIC_CWDE,
    MNEMONIC_DAA,
    MNEMONIC_DAS,
    MNEMONIC_DEC,
    MNEMONIC_DELAY,
    MNEMONIC_DIV,
    MNEMONIC_DIVPD,
    MNEMONIC_DIVPS,
    MNEMONIC_DIVSD,
    MNEMONIC_DIVSS,
    MNEMONIC_DPPD,
    MNEMONIC_DPPS,
    MNEMONIC_EMMS,
    MNEMONIC_ENCLS,
    MNEMONIC_ENCLU,
    MNEMONIC_ENCLV,
    MNEMONIC_ENDBR32,
    MNEMONIC_ENDBR64,
    MNEMONIC_ENQCMD,
    MNEMONIC_ENQCMDS,
    MNEMONIC_ENTER,
    MNEMONIC_EXTRACTPS,
    MNEMONIC_EXTRQ,
    MNEMONIC_F2XM1,
    MNEMONIC_FABS,
    MNEMONIC_FADD,
    MNEMONIC_FADDP,
    MNEMONIC_FBLD,
    MNEMONIC_FBSTP,
    MNEMONIC_FCHS,
    MNEMONIC_FCMOVB,
    MNEMONIC_FCMOVBE,
    MNEMONIC_FCMOVE,
    MNEMONIC_FCMOVNB,
    MNEMONIC_FCMOVNBE,
    MNEMONIC_FCMOVNE,
    MNEMONIC_FCMOVNU,
    MNEMONIC_FCMOVU,
    MNEMONIC_FCOM,
    MNEMONIC_FCOMI,
    MNEMONIC_FCOMIP,
    MNEMONIC_FCOMP,
    MNEMONIC_FCOMPP,
    MNEMONIC_FCOS,
    MNEMONIC_FDECSTP,
    MNEMONIC_FDISI8087_NOP,
    MNEMONIC_FDIV,
    MNEMONIC_FDIVP,
    MNEMONIC_FDIVR,
    MNEMONIC_FDIVRP,
    MNEMONIC_FEMMS,
    MNEMONIC_FENI8087_NOP,
    MNEMONIC_FFREE,
    MNEMONIC_FFREEP,
    MNEMONIC_FIADD,
    MNEMONIC_FICOM,
    MNEMONIC_FICOMP,
    MNEMONIC_FIDIV,
    MNEMONIC_FIDIVR,
    MNEMONIC_FILD,
    MNEMONIC_FIMUL,
    MNEMONIC_FINCSTP,
    MNEMONIC_FIST,
    MNEMONIC_FISTP,
    MNEMONIC_FISTTP,
    MNEMONIC_FISUB,
    MNEMONIC_FISUBR,
    MNEMONIC_FLD,
    MNEMONIC_FLD1,
    MNEMONIC_FLDCW,
    MNEMONIC_FLDENV,
    MNEMONIC_FLDL2E,
    MNEMONIC_FLDL2T,
    MNEMONIC_FLDLG2,
    MNEMONIC_FLDLN2,
    MNEMONIC_FLDPI,
    MNEMONIC_FLDZ,
    MNEMONIC_FMUL,
    MNEMONIC_FMULP,
    MNEMONIC_FNCLEX,
    MNEMONIC_FNINIT,
    MNEMONIC_FNOP,
    MNEMONIC_FNSAVE,
    MNEMONIC_FNSTCW,
    MNEMONIC_FNSTENV,
    MNEMONIC_FNSTSW,
    MNEMONIC_FPATAN,
    MNEMONIC_FPREM,
    MNEMONIC_FPREM1,
    MNEMONIC_FPTAN,
    MNEMONIC_FRNDINT,
    MNEMONIC_FRSTOR,
    MNEMONIC_FSCALE,
    MNEMONIC_FSETPM287_NOP,
    MNEMONIC_FSIN,
    MNEMONIC_FSINCOS,
    MNEMONIC_FSQRT,
    MNEMONIC_FST,
    MNEMONIC_FSTP,
    MNEMONIC_FSTPNCE,
    MNEMONIC_FSUB,
    MNEMONIC_FSUBP,
    MNEMONIC_FSUBR,
    MNEMONIC_FSUBRP,
    MNEMONIC_FTST,
    MNEMONIC_FUCOM,
    MNEMONIC_FUCOMI,
    MNEMONIC_FUCOMIP,
    MNEMONIC_FUCOMP,
    MNEMONIC_FUCOMPP,
    MNEMONIC_FWAIT,
    MNEMONIC_FXAM,
    MNEMONIC_FXCH,
    MNEMONIC_FXRSTOR,
    MNEMONIC_FXRSTOR64,
    MNEMONIC_FXSAVE,
    MNEMONIC_FXSAVE64,
    MNEMONIC_FXTRACT,
    MNEMONIC_FYL2X,
    MNEMONIC_FYL2XP1,
    MNEMONIC_GETSEC,
    MNEMONIC_GF2P8AFFINEINVQB,
    MNEMONIC_GF2P8AFFINEQB,
    MNEMONIC_GF2P8MULB,
    MNEMONIC_HADDPD,
    MNEMONIC_HADDPS,
    MNEMONIC_HLT,
    MNEMONIC_HSUBPD,
    MNEMONIC_HSUBPS,
    MNEMONIC_IDIV,
    MNEMONIC_IMUL,
    MNEMONIC_IN,
    MNEMONIC_INC,
    MNEMONIC_INCSSPD,
    MNEMONIC_INCSSPQ,
    MNEMONIC_INSB,
    MNEMONIC_INSD,
    MNEMONIC_INSERTPS,
    MNEMONIC_INSERTQ,
    MNEMONIC_INSW,
    MNEMONIC_INT,
    MNEMONIC_INT1,
    MNEMONIC_INT3,
    MNEMONIC_INTO,
    MNEMONIC_INVD,
    MNEMONIC_INVEPT,
    MNEMONIC_INVLPG,
    MNEMONIC_INVLPGA,
    MNEMONIC_INVLPGB,
    MNEMONIC_INVPCID,
    MNEMONIC_INVVPID,
    MNEMONIC_IRET,
    MNEMONIC_IRETD,
    MNEMONIC_IRETQ,
    MNEMONIC_JB,
    MNEMONIC_JBE,
    MNEMONIC_JCXZ,
    MNEMONIC_JECXZ,
    MNEMONIC_JKNZD,
    MNEMONIC_JKZD,
    MNEMONIC_JL,
    MNEMONIC_JLE,
    MNEMONIC_JMP,
    MNEMONIC_JNB,
    MNEMONIC_JNBE,
    MNEMONIC_JNL,
    MNEMONIC_JNLE,
    MNEMONIC_JNO,
    MNEMONIC_JNP,
    MNEMONIC_JNS,
    MNEMONIC_JNZ,
    MNEMONIC_JO,
    MNEMONIC_JP,
    MNEMONIC_JRCXZ,
    MNEMONIC_JS,
    MNEMONIC_JZ,
    MNEMONIC_KADDB,
    MNEMONIC_KADDD,
    MNEMONIC_KADDQ,
    MNEMONIC_KADDW,
    MNEMONIC_KAND,
    MNEMONIC_KANDB,
    MNEMONIC_KANDD,
    MNEMONIC_KANDN,
    MNEMONIC_KANDNB,
    MNEMONIC_KANDND,
    MNEMONIC_KANDNQ,
    MNEMONIC_KANDNR,
    MNEMONIC_KANDNW,
    MNEMONIC_KANDQ,
    MNEMONIC_KANDW,
    MNEMONIC_KCONCATH,
    MNEMONIC_KCONCATL,
    MNEMONIC_KEXTRACT,
    MNEMONIC_KMERGE2L1H,
    MNEMONIC_KMERGE2L1L,
    MNEMONIC_KMOV,
    MNEMONIC_KMOVB,
    MNEMONIC_KMOVD,
    MNEMONIC_KMOVQ,
    MNEMONIC_KMOVW,
    MNEMONIC_KNOT,
    MNEMONIC_KNOTB,
    MNEMONIC_KNOTD,
    MNEMONIC_KNOTQ,
    MNEMONIC_KNOTW,
    MNEMONIC_KOR,
    MNEMONIC_KORB,
    MNEMONIC_KORD,
    MNEMONIC_KORQ,
    MNEMONIC_KORTEST,
    MNEMONIC_KORTESTB,
    MNEMONIC_KORTESTD,
    MNEMONIC_KORTESTQ,
    MNEMONIC_KORTESTW,
    MNEMONIC_KORW,
    MNEMONIC_KSHIFTLB,
    MNEMONIC_KSHIFTLD,
    MNEMONIC_KSHIFTLQ,
    MNEMONIC_KSHIFTLW,
    MNEMONIC_KSHIFTRB,
    MNEMONIC_KSHIFTRD,
    MNEMONIC_KSHIFTRQ,
    MNEMONIC_KSHIFTRW,
    MNEMONIC_KTESTB,
    MNEMONIC_KTESTD,
    MNEMONIC_KTESTQ,
    MNEMONIC_KTESTW,
    MNEMONIC_KUNPCKBW,
    MNEMONIC_KUNPCKDQ,
    MNEMONIC_KUNPCKWD,
    MNEMONIC_KXNOR,
    MNEMONIC_KXNORB,
    MNEMONIC_KXNORD,
    MNEMONIC_KXNORQ,
    MNEMONIC_KXNORW,
    MNEMONIC_KXOR,
    MNEMONIC_KXORB,
    MNEMONIC_KXORD,
    MNEMONIC_KXORQ,
    MNEMONIC_KXORW,
    MNEMONIC_LAHF,
    MNEMONIC_LAR,
    MNEMONIC_LDDQU,
    MNEMONIC_LDMXCSR,
    MNEMONIC_LDS,
    MNEMONIC_LDTILECFG,
    MNEMONIC_LEA,
    MNEMONIC_LEAVE,
    MNEMONIC_LES,
    MNEMONIC_LFENCE,
    MNEMONIC_LFS,
    MNEMONIC_LGDT,
    MNEMONIC_LGS,
    MNEMONIC_LIDT,
    MNEMONIC_LLDT,
    MNEMONIC_LLWPCB,
    MNEMONIC_LMSW,
    MNEMONIC_LODSB,
    MNEMONIC_LODSD,
    MNEMONIC_LODSQ,
    MNEMONIC_LODSW,
    MNEMONIC_LOOP,
    MNEMONIC_LOOPE,
    MNEMONIC_LOOPNE,
    MNEMONIC_LSL,
    MNEMONIC_LSS,
    MNEMONIC_LTR,
    MNEMONIC_LWPINS,
    MNEMONIC_LWPVAL,
    MNEMONIC_LZCNT,
    MNEMONIC_MASKMOVDQU,
    MNEMONIC_MASKMOVQ,
    MNEMONIC_MAXPD,
    MNEMONIC_MAXPS,
    MNEMONIC_MAXSD,
    MNEMONIC_MAXSS,
    MNEMONIC_MCOMMIT,
    MNEMONIC_MFENCE,
    MNEMONIC_MINPD,
    MNEMONIC_MINPS,
    MNEMONIC_MINSD,
    MNEMONIC_MINSS,
    MNEMONIC_MONITOR,
    MNEMONIC_MONITORX,
    MNEMONIC_MONTMUL,
    MNEMONIC_MOV,
    MNEMONIC_MOVAPD,
    MNEMONIC_MOVAPS,
    MNEMONIC_MOVBE,
    MNEMONIC_MOVD,
    MNEMONIC_MOVDDUP,
    MNEMONIC_MOVDIR64B,
    MNEMONIC_MOVDIRI,
    MNEMONIC_MOVDQ2Q,
    MNEMONIC_MOVDQA,
    MNEMONIC_MOVDQU,
    MNEMONIC_MOVHLPS,
    MNEMONIC_MOVHPD,
    MNEMONIC_MOVHPS,
    MNEMONIC_MOVLHPS,
    MNEMONIC_MOVLPD,
    MNEMONIC_MOVLPS,
    MNEMONIC_MOVMSKPD,
    MNEMONIC_MOVMSKPS,
    MNEMONIC_MOVNTDQ,
    MNEMONIC_MOVNTDQA,
    MNEMONIC_MOVNTI,
    MNEMONIC_MOVNTPD,
    MNEMONIC_MOVNTPS,
    MNEMONIC_MOVNTQ,
    MNEMONIC_MOVNTSD,
    MNEMONIC_MOVNTSS,
    MNEMONIC_MOVQ,
    MNEMONIC_MOVQ2DQ,
    MNEMONIC_MOVSB,
    MNEMONIC_MOVSD,
    MNEMONIC_MOVSHDUP,
    MNEMONIC_MOVSLDUP,
    MNEMONIC_MOVSQ,
    MNEMONIC_MOVSS,
    MNEMONIC_MOVSW,
    MNEMONIC_MOVSX,
    MNEMONIC_MOVSXD,
    MNEMONIC_MOVUPD,
    MNEMONIC_MOVUPS,
    MNEMONIC_MOVZX,
    MNEMONIC_MPSADBW,
    MNEMONIC_MUL,
    MNEMONIC_MULPD,
    MNEMONIC_MULPS,
    MNEMONIC_MULSD,
    MNEMONIC_MULSS,
    MNEMONIC_MULX,
    MNEMONIC_MWAIT,
    MNEMONIC_MWAITX,
    MNEMONIC_NEG,
    MNEMONIC_NOP,
    MNEMONIC_NOT,
    MNEMONIC_OR,
    MNEMONIC_ORPD,
    MNEMONIC_ORPS,
    MNEMONIC_OUT,
    MNEMONIC_OUTSB,
    MNEMONIC_OUTSD,
    MNEMONIC_OUTSW,
    MNEMONIC_PABSB,
    MNEMONIC_PABSD,
    MNEMONIC_PABSW,
    MNEMONIC_PACKSSDW,
    MNEMONIC_PACKSSWB,
    MNEMONIC_PACKUSDW,
    MNEMONIC_PACKUSWB,
    MNEMONIC_PADDB,
    MNEMONIC_PADDD,
    MNEMONIC_PADDQ,
    MNEMONIC_PADDSB,
    MNEMONIC_PADDSW,
    MNEMONIC_PADDUSB,
    MNEMONIC_PADDUSW,
    MNEMONIC_PADDW,
    MNEMONIC_PALIGNR,
    MNEMONIC_PAND,
    MNEMONIC_PANDN,
    MNEMONIC_PAUSE,
    MNEMONIC_PAVGB,
    MNEMONIC_PAVGUSB,
    MNEMONIC_PAVGW,
    MNEMONIC_PBLENDVB,
    MNEMONIC_PBLENDW,
    MNEMONIC_PCLMULQDQ,
    MNEMONIC_PCMPEQB,
    MNEMONIC_PCMPEQD,
    MNEMONIC_PCMPEQQ,
    MNEMONIC_PCMPEQW,
    MNEMONIC_PCMPESTRI,
    MNEMONIC_PCMPESTRM,
    MNEMONIC_PCMPGTB,
    MNEMONIC_PCMPGTD,
    MNEMONIC_PCMPGTQ,
    MNEMONIC_PCMPGTW,
    MNEMONIC_PCMPISTRI,
    MNEMONIC_PCMPISTRM,
    MNEMONIC_PCONFIG,
    MNEMONIC_PDEP,
    MNEMONIC_PEXT,
    MNEMONIC_PEXTRB,
    MNEMONIC_PEXTRD,
    MNEMONIC_PEXTRQ,
    MNEMONIC_PEXTRW,
    MNEMONIC_PF2ID,
    MNEMONIC_PF2IW,
    MNEMONIC_PFACC,
    MNEMONIC_PFADD,
    MNEMONIC_PFCMPEQ,
    MNEMONIC_PFCMPGE,
    MNEMONIC_PFCMPGT,
    MNEMONIC_PFCPIT1,
    MNEMONIC_PFMAX,
    MNEMONIC_PFMIN,
    MNEMONIC_PFMUL,
    MNEMONIC_PFNACC,
    MNEMONIC_PFPNACC,
    MNEMONIC_PFRCP,
    MNEMONIC_PFRCPIT2,
    MNEMONIC_PFRSQIT1,
    MNEMONIC_PFSQRT,
    MNEMONIC_PFSUB,
    MNEMONIC_PFSUBR,
    MNEMONIC_PHADDD,
    MNEMONIC_PHADDSW,
    MNEMONIC_PHADDW,
    MNEMONIC_PHMINPOSUW,
    MNEMONIC_PHSUBD,
    MNEMONIC_PHSUBSW,
    MNEMONIC_PHSUBW,
    MNEMONIC_PI2FD,
    MNEMONIC_PI2FW,
    MNEMONIC_PINSRB,
    MNEMONIC_PINSRD,
    MNEMONIC_PINSRQ,
    MNEMONIC_PINSRW,
    MNEMONIC_PMADDUBSW,
    MNEMONIC_PMADDWD,
    MNEMONIC_PMAXSB,
    MNEMONIC_PMAXSD,
    MNEMONIC_PMAXSW,
    MNEMONIC_PMAXUB,
    MNEMONIC_PMAXUD,
    MNEMONIC_PMAXUW,
    MNEMONIC_PMINSB,
    MNEMONIC_PMINSD,
    MNEMONIC_PMINSW,
    MNEMONIC_PMINUB,
    MNEMONIC_PMINUD,
    MNEMONIC_PMINUW,
    MNEMONIC_PMOVMSKB,
    MNEMONIC_PMOVSXBD,
    MNEMONIC_PMOVSXBQ,
    MNEMONIC_PMOVSXBW,
    MNEMONIC_PMOVSXDQ,
    MNEMONIC_PMOVSXWD,
    MNEMONIC_PMOVSXWQ,
    MNEMONIC_PMOVZXBD,
    MNEMONIC_PMOVZXBQ,
    MNEMONIC_PMOVZXBW,
    MNEMONIC_PMOVZXDQ,
    MNEMONIC_PMOVZXWD,
    MNEMONIC_PMOVZXWQ,
    MNEMONIC_PMULDQ,
    MNEMONIC_PMULHRSW,
    MNEMONIC_PMULHRW,
    MNEMONIC_PMULHUW,
    MNEMONIC_PMULHW,
    MNEMONIC_PMULLD,
    MNEMONIC_PMULLW,
    MNEMONIC_PMULUDQ,
    MNEMONIC_POP,
    MNEMONIC_POPA,
    MNEMONIC_POPAD,
    MNEMONIC_POPCNT,
    MNEMONIC_POPF,
    MNEMONIC_POPFD,
    MNEMONIC_POPFQ,
    MNEMONIC_POR,
    MNEMONIC_PREFETCH,
    MNEMONIC_PREFETCHNTA,
    MNEMONIC_PREFETCHT0,
    MNEMONIC_PREFETCHT1,
    MNEMONIC_PREFETCHT2,
    MNEMONIC_PREFETCHW,
    MNEMONIC_PREFETCHWT1,
    MNEMONIC_PSADBW,
    MNEMONIC_PSHUFB,
    MNEMONIC_PSHUFD,
    MNEMONIC_PSHUFHW,
    MNEMONIC_PSHUFLW,
    MNEMONIC_PSHUFW,
    MNEMONIC_PSIGNB,
    MNEMONIC_PSIGND,
    MNEMONIC_PSIGNW,
    MNEMONIC_PSLLD,
    MNEMONIC_PSLLDQ,
    MNEMONIC_PSLLQ,
    MNEMONIC_PSLLW,
    MNEMONIC_PSMASH,
    MNEMONIC_PSRAD,
    MNEMONIC_PSRAW,
    MNEMONIC_PSRLD,
    MNEMONIC_PSRLDQ,
    MNEMONIC_PSRLQ,
    MNEMONIC_PSRLW,
    MNEMONIC_PSUBB,
    MNEMONIC_PSUBD,
    MNEMONIC_PSUBQ,
    MNEMONIC_PSUBSB,
    MNEMONIC_PSUBSW,
    MNEMONIC_PSUBUSB,
    MNEMONIC_PSUBUSW,
    MNEMONIC_PSUBW,
    MNEMONIC_PSWAPD,
    MNEMONIC_PTEST,
    MNEMONIC_PTWRITE,
    MNEMONIC_PUNPCKHBW,
    MNEMONIC_PUNPCKHDQ,
    MNEMONIC_PUNPCKHQDQ,
    MNEMONIC_PUNPCKHWD,
    MNEMONIC_PUNPCKLBW,
    MNEMONIC_PUNPCKLDQ,
    MNEMONIC_PUNPCKLQDQ,
    MNEMONIC_PUNPCKLWD,
    MNEMONIC_PUSH,
    MNEMONIC_PUSHA,
    MNEMONIC_PUSHAD,
    MNEMONIC_PUSHF,
    MNEMONIC_PUSHFD,
    MNEMONIC_PUSHFQ,
    MNEMONIC_PVALIDATE,
    MNEMONIC_PXOR,
    MNEMONIC_RCL,
    MNEMONIC_RCPPS,
    MNEMONIC_RCPSS,
    MNEMONIC_RCR,
    MNEMONIC_RDFSBASE,
    MNEMONIC_RDGSBASE,
    MNEMONIC_RDMSR,
    MNEMONIC_RDPID,
    MNEMONIC_RDPKRU,
    MNEMONIC_RDPMC,
    MNEMONIC_RDPRU,
    MNEMONIC_RDRAND,
    MNEMONIC_RDSEED,
    MNEMONIC_RDSSPD,
    MNEMONIC_RDSSPQ,
    MNEMONIC_RDTSC,
    MNEMONIC_RDTSCP,
    MNEMONIC_RET,
    MNEMONIC_RMPADJUST,
    MNEMONIC_RMPUPDATE,
    MNEMONIC_ROL,
    MNEMONIC_ROR,
    MNEMONIC_RORX,
    MNEMONIC_ROUNDPD,
    MNEMONIC_ROUNDPS,
    MNEMONIC_ROUNDSD,
    MNEMONIC_ROUNDSS,
    MNEMONIC_RSM,
    MNEMONIC_RSQRTPS,
    MNEMONIC_RSQRTSS,
    MNEMONIC_RSTORSSP,
    MNEMONIC_SAHF,
    MNEMONIC_SALC,
    MNEMONIC_SAR,
    MNEMONIC_SARX,
    MNEMONIC_SAVEPREVSSP,
    MNEMONIC_SBB,
    MNEMONIC_SCASB,
    MNEMONIC_SCASD,
    MNEMONIC_SCASQ,
    MNEMONIC_SCASW,
    MNEMONIC_SERIALIZE,
    MNEMONIC_SETB,
    MNEMONIC_SETBE,
    MNEMONIC_SETL,
    MNEMONIC_SETLE,
    MNEMONIC_SETNB,
    MNEMONIC_SETNBE,
    MNEMONIC_SETNL,
    MNEMONIC_SETNLE,
    MNEMONIC_SETNO,
    MNEMONIC_SETNP,
    MNEMONIC_SETNS,
    MNEMONIC_SETNZ,
    MNEMONIC_SETO,
    MNEMONIC_SETP,
    MNEMONIC_SETS,
    MNEMONIC_SETSSBSY,
    MNEMONIC_SETZ,
    MNEMONIC_SFENCE,
    MNEMONIC_SGDT,
    MNEMONIC_SHA1MSG1,
    MNEMONIC_SHA1MSG2,
    MNEMONIC_SHA1NEXTE,
    MNEMONIC_SHA1RNDS4,
    MNEMONIC_SHA256MSG1,
    MNEMONIC_SHA256MSG2,
    MNEMONIC_SHA256RNDS2,
    MNEMONIC_SHL,
    MNEMONIC_SHLD,
    MNEMONIC_SHLX,
    MNEMONIC_SHR,
    MNEMONIC_SHRD,
    MNEMONIC_SHRX,
    MNEMONIC_SHUFPD,
    MNEMONIC_SHUFPS,
    MNEMONIC_SIDT,
    MNEMONIC_SKINIT,
    MNEMONIC_SLDT,
    MNEMONIC_SLWPCB,
    MNEMONIC_SMSW,
    MNEMONIC_SPFLT,
    MNEMONIC_SQRTPD,
    MNEMONIC_SQRTPS,
    MNEMONIC_SQRTSD,
    MNEMONIC_SQRTSS,
    MNEMONIC_STAC,
    MNEMONIC_STC,
    MNEMONIC_STD,
    MNEMONIC_STGI,
    MNEMONIC_STI,
    MNEMONIC_STMXCSR,
    MNEMONIC_STOSB,
    MNEMONIC_STOSD,
    MNEMONIC_STOSQ,
    MNEMONIC_STOSW,
    MNEMONIC_STR,
    MNEMONIC_STTILECFG,
    MNEMONIC_SUB,
    MNEMONIC_SUBPD,
    MNEMONIC_SUBPS,
    MNEMONIC_SUBSD,
    MNEMONIC_SUBSS,
    MNEMONIC_SWAPGS,
    MNEMONIC_SYSCALL,
    MNEMONIC_SYSENTER,
    MNEMONIC_SYSEXIT,
    MNEMONIC_SYSRET,
    MNEMONIC_T1MSKC,
    MNEMONIC_TDPBF16PS,
    MNEMONIC_TDPBSSD,
    MNEMONIC_TDPBSUD,
    MNEMONIC_TDPBUSD,
    MNEMONIC_TDPBUUD,
    MNEMONIC_TEST,
    MNEMONIC_TILELOADD,
    MNEMONIC_TILELOADDT1,
    MNEMONIC_TILERELEASE,
    MNEMONIC_TILESTORED,
    MNEMONIC_TILEZERO,
    MNEMONIC_TLBSYNC,
    MNEMONIC_TPAUSE,
    MNEMONIC_TZCNT,
    MNEMONIC_TZCNTI,
    MNEMONIC_TZMSK,
    MNEMONIC_UCOMISD,
    MNEMONIC_UCOMISS,
    MNEMONIC_UD0,
    MNEMONIC_UD1,
    MNEMONIC_UD2,
    MNEMONIC_UMONITOR,
    MNEMONIC_UMWAIT,
    MNEMONIC_UNPCKHPD,
    MNEMONIC_UNPCKHPS,
    MNEMONIC_UNPCKLPD,
    MNEMONIC_UNPCKLPS,
    MNEMONIC_V4FMADDPS,
    MNEMONIC_V4FMADDSS,
    MNEMONIC_V4FNMADDPS,
    MNEMONIC_V4FNMADDSS,
    MNEMONIC_VADDNPD,
    MNEMONIC_VADDNPS,
    MNEMONIC_VADDPD,
    MNEMONIC_VADDPS,
    MNEMONIC_VADDSD,
    MNEMONIC_VADDSETSPS,
    MNEMONIC_VADDSS,
    MNEMONIC_VADDSUBPD,
    MNEMONIC_VADDSUBPS,
    MNEMONIC_VAESDEC,
    MNEMONIC_VAESDECLAST,
    MNEMONIC_VAESENC,
    MNEMONIC_VAESENCLAST,
    MNEMONIC_VAESIMC,
    MNEMONIC_VAESKEYGENASSIST,
    MNEMONIC_VALIGND,
    MNEMONIC_VALIGNQ,
    MNEMONIC_VANDNPD,
    MNEMONIC_VANDNPS,
    MNEMONIC_VANDPD,
    MNEMONIC_VANDPS,
    MNEMONIC_VBLENDMPD,
    MNEMONIC_VBLENDMPS,
    MNEMONIC_VBLENDPD,
    MNEMONIC_VBLENDPS,
    MNEMONIC_VBLENDVPD,
    MNEMONIC_VBLENDVPS,
    MNEMONIC_VBROADCASTF128,
    MNEMONIC_VBROADCASTF32X2,
    MNEMONIC_VBROADCASTF32X4,
    MNEMONIC_VBROADCASTF32X8,
    MNEMONIC_VBROADCASTF64X2,
    MNEMONIC_VBROADCASTF64X4,
    MNEMONIC_VBROADCASTI128,
    MNEMONIC_VBROADCASTI32X2,
    MNEMONIC_VBROADCASTI32X4,
    MNEMONIC_VBROADCASTI32X8,
    MNEMONIC_VBROADCASTI64X2,
    MNEMONIC_VBROADCASTI64X4,
    MNEMONIC_VBROADCASTSD,
    MNEMONIC_VBROADCASTSS,
    MNEMONIC_VCMPPD,
    MNEMONIC_VCMPPS,
    MNEMONIC_VCMPSD,
    MNEMONIC_VCMPSS,
    MNEMONIC_VCOMISD,
    MNEMONIC_VCOMISS,
    MNEMONIC_VCOMPRESSPD,
    MNEMONIC_VCOMPRESSPS,
    MNEMONIC_VCVTDQ2PD,
    MNEMONIC_VCVTDQ2PS,
    MNEMONIC_VCVTFXPNTDQ2PS,
    MNEMONIC_VCVTFXPNTPD2DQ,
    MNEMONIC_VCVTFXPNTPD2UDQ,
    MNEMONIC_VCVTFXPNTPS2DQ,
    MNEMONIC_VCVTFXPNTPS2UDQ,
    MNEMONIC_VCVTFXPNTUDQ2PS,
    MNEMONIC_VCVTNE2PS2BF16,
    MNEMONIC_VCVTNEPS2BF16,
    MNEMONIC_VCVTPD2DQ,
    MNEMONIC_VCVTPD2PS,
    MNEMONIC_VCVTPD2QQ,
    MNEMONIC_VCVTPD2UDQ,
    MNEMONIC_VCVTPD2UQQ,
    MNEMONIC_VCVTPH2PS,
    MNEMONIC_VCVTPS2DQ,
    MNEMONIC_VCVTPS2PD,
    MNEMONIC_VCVTPS2PH,
    MNEMONIC_VCVTPS2QQ,
    MNEMONIC_VCVTPS2UDQ,
    MNEMONIC_VCVTPS2UQQ,
    MNEMONIC_VCVTQQ2PD,
    MNEMONIC_VCVTQQ2PS,
    MNEMONIC_VCVTSD2SI,
    MNEMONIC_VCVTSD2SS,
    MNEMONIC_VCVTSD2USI,
    MNEMONIC_VCVTSI2SD,
    MNEMONIC_VCVTSI2SS,
    MNEMONIC_VCVTSS2SD,
    MNEMONIC_VCVTSS2SI,
    MNEMONIC_VCVTSS2USI,
    MNEMONIC_VCVTTPD2DQ,
    MNEMONIC_VCVTTPD2QQ,
    MNEMONIC_VCVTTPD2UDQ,
    MNEMONIC_VCVTTPD2UQQ,
    MNEMONIC_VCVTTPS2DQ,
    MNEMONIC_VCVTTPS2QQ,
    MNEMONIC_VCVTTPS2UDQ,
    MNEMONIC_VCVTTPS2UQQ,
    MNEMONIC_VCVTTSD2SI,
    MNEMONIC_VCVTTSD2USI,
    MNEMONIC_VCVTTSS2SI,
    MNEMONIC_VCVTTSS2USI,
    MNEMONIC_VCVTUDQ2PD,
    MNEMONIC_VCVTUDQ2PS,
    MNEMONIC_VCVTUQQ2PD,
    MNEMONIC_VCVTUQQ2PS,
    MNEMONIC_VCVTUSI2SD,
    MNEMONIC_VCVTUSI2SS,
    MNEMONIC_VDBPSADBW,
    MNEMONIC_VDIVPD,
    MNEMONIC_VDIVPS,
    MNEMONIC_VDIVSD,
    MNEMONIC_VDIVSS,
    MNEMONIC_VDPBF16PS,
    MNEMONIC_VDPPD,
    MNEMONIC_VDPPS,
    MNEMONIC_VERR,
    MNEMONIC_VERW,
    MNEMONIC_VEXP223PS,
    MNEMONIC_VEXP2PD,
    MNEMONIC_VEXP2PS,
    MNEMONIC_VEXPANDPD,
    MNEMONIC_VEXPANDPS,
    MNEMONIC_VEXTRACTF128,
    MNEMONIC_VEXTRACTF32X4,
    MNEMONIC_VEXTRACTF32X8,
    MNEMONIC_VEXTRACTF64X2,
    MNEMONIC_VEXTRACTF64X4,
    MNEMONIC_VEXTRACTI128,
    MNEMONIC_VEXTRACTI32X4,
    MNEMONIC_VEXTRACTI32X8,
    MNEMONIC_VEXTRACTI64X2,
    MNEMONIC_VEXTRACTI64X4,
    MNEMONIC_VEXTRACTPS,
    MNEMONIC_VFIXUPIMMPD,
    MNEMONIC_VFIXUPIMMPS,
    MNEMONIC_VFIXUPIMMSD,
    MNEMONIC_VFIXUPIMMSS,
    MNEMONIC_VFIXUPNANPD,
    MNEMONIC_VFIXUPNANPS,
    MNEMONIC_VFMADD132PD,
    MNEMONIC_VFMADD132PS,
    MNEMONIC_VFMADD132SD,
    MNEMONIC_VFMADD132SS,
    MNEMONIC_VFMADD213PD,
    MNEMONIC_VFMADD213PS,
    MNEMONIC_VFMADD213SD,
    MNEMONIC_VFMADD213SS,
    MNEMONIC_VFMADD231PD,
    MNEMONIC_VFMADD231PS,
    MNEMONIC_VFMADD231SD,
    MNEMONIC_VFMADD231SS,
    MNEMONIC_VFMADD233PS,
    MNEMONIC_VFMADDPD,
    MNEMONIC_VFMADDPS,
    MNEMONIC_VFMADDSD,
    MNEMONIC_VFMADDSS,
    MNEMONIC_VFMADDSUB132PD,
    MNEMONIC_VFMADDSUB132PS,
    MNEMONIC_VFMADDSUB213PD,
    MNEMONIC_VFMADDSUB213PS,
    MNEMONIC_VFMADDSUB231PD,
    MNEMONIC_VFMADDSUB231PS,
    MNEMONIC_VFMADDSUBPD,
    MNEMONIC_VFMADDSUBPS,
    MNEMONIC_VFMSUB132PD,
    MNEMONIC_VFMSUB132PS,
    MNEMONIC_VFMSUB132SD,
    MNEMONIC_VFMSUB132SS,
    MNEMONIC_VFMSUB213PD,
    MNEMONIC_VFMSUB213PS,
    MNEMONIC_VFMSUB213SD,
    MNEMONIC_VFMSUB213SS,
    MNEMONIC_VFMSUB231PD,
    MNEMONIC_VFMSUB231PS,
    MNEMONIC_VFMSUB231SD,
    MNEMONIC_VFMSUB231SS,
    MNEMONIC_VFMSUBADD132PD,
    MNEMONIC_VFMSUBADD132PS,
    MNEMONIC_VFMSUBADD213PD,
    MNEMONIC_VFMSUBADD213PS,
    MNEMONIC_VFMSUBADD231PD,
    MNEMONIC_VFMSUBADD231PS,
    MNEMONIC_VFMSUBADDPD,
    MNEMONIC_VFMSUBADDPS,
    MNEMONIC_VFMSUBPD,
    MNEMONIC_VFMSUBPS,
    MNEMONIC_VFMSUBSD,
    MNEMONIC_VFMSUBSS,
    MNEMONIC_VFNMADD132PD,
    MNEMONIC_VFNMADD132PS,
    MNEMONIC_VFNMADD132SD,
    MNEMONIC_VFNMADD132SS,
    MNEMONIC_VFNMADD213PD,
    MNEMONIC_VFNMADD213PS,
    MNEMONIC_VFNMADD213SD,
    MNEMONIC_VFNMADD213SS,
    MNEMONIC_VFNMADD231PD,
    MNEMONIC_VFNMADD231PS,
    MNEMONIC_VFNMADD231SD,
    MNEMONIC_VFNMADD231SS,
    MNEMONIC_VFNMADDPD,
    MNEMONIC_VFNMADDPS,
    MNEMONIC_VFNMADDSD,
    MNEMONIC_VFNMADDSS,
    MNEMONIC_VFNMSUB132PD,
    MNEMONIC_VFNMSUB132PS,
    MNEMONIC_VFNMSUB132SD,
    MNEMONIC_VFNMSUB132SS,
    MNEMONIC_VFNMSUB213PD,
    MNEMONIC_VFNMSUB213PS,
    MNEMONIC_VFNMSUB213SD,
    MNEMONIC_VFNMSUB213SS,
    MNEMONIC_VFNMSUB231PD,
    MNEMONIC_VFNMSUB231PS,
    MNEMONIC_VFNMSUB231SD,
    MNEMONIC_VFNMSUB231SS,
    MNEMONIC_VFNMSUBPD,
    MNEMONIC_VFNMSUBPS,
    MNEMONIC_VFNMSUBSD,
    MNEMONIC_VFNMSUBSS,
    MNEMONIC_VFPCLASSPD,
    MNEMONIC_VFPCLASSPS,
    MNEMONIC_VFPCLASSSD,
    MNEMONIC_VFPCLASSSS,
    MNEMONIC_VFRCZPD,
    MNEMONIC_VFRCZPS,
    MNEMONIC_VFRCZSD,
    MNEMONIC_VFRCZSS,
    MNEMONIC_VGATHERDPD,
    MNEMONIC_VGATHERDPS,
    MNEMONIC_VGATHERPF0DPD,
    MNEMONIC_VGATHERPF0DPS,
    MNEMONIC_VGATHERPF0HINTDPD,
    MNEMONIC_VGATHERPF0HINTDPS,
    MNEMONIC_VGATHERPF0QPD,
    MNEMONIC_VGATHERPF0QPS,
    MNEMONIC_VGATHERPF1DPD,
    MNEMONIC_VGATHERPF1DPS,
    MNEMONIC_VGATHERPF1QPD,
    MNEMONIC_VGATHERPF1QPS,
    MNEMONIC_VGATHERQPD,
    MNEMONIC_VGATHERQPS,
    MNEMONIC_VGETEXPPD,
    MNEMONIC_VGETEXPPS,
    MNEMONIC_VGETEXPSD,
    MNEMONIC_VGETEXPSS,
    MNEMONIC_VGETMANTPD,
    MNEMONIC_VGETMANTPS,
    MNEMONIC_VGETMANTSD,
    MNEMONIC_VGETMANTSS,
    MNEMONIC_VGF2P8AFFINEINVQB,
    MNEMONIC_VGF2P8AFFINEQB,
    MNEMONIC_VGF2P8MULB,
    MNEMONIC_VGMAXABSPS,
    MNEMONIC_VGMAXPD,
    MNEMONIC_VGMAXPS,
    MNEMONIC_VGMINPD,
    MNEMONIC_VGMINPS,
    MNEMONIC_VHADDPD,
    MNEMONIC_VHADDPS,
    MNEMONIC_VHSUBPD,
    MNEMONIC_VHSUBPS,
    MNEMONIC_VINSERTF128,
    MNEMONIC_VINSERTF32X4,
    MNEMONIC_VINSERTF32X8,
    MNEMONIC_VINSERTF64X2,
    MNEMONIC_VINSERTF64X4,
    MNEMONIC_VINSERTI128,
    MNEMONIC_VINSERTI32X4,
    MNEMONIC_VINSERTI32X8,
    MNEMONIC_VINSERTI64X2,
    MNEMONIC_VINSERTI64X4,
    MNEMONIC_VINSERTPS,
    MNEMONIC_VLDDQU,
    MNEMONIC_VLDMXCSR,
    MNEMONIC_VLOADUNPACKHD,
    MNEMONIC_VLOADUNPACKHPD,
    MNEMONIC_VLOADUNPACKHPS,
    MNEMONIC_VLOADUNPACKHQ,
    MNEMONIC_VLOADUNPACKLD,
    MNEMONIC_VLOADUNPACKLPD,
    MNEMONIC_VLOADUNPACKLPS,
    MNEMONIC_VLOADUNPACKLQ,
    MNEMONIC_VLOG2PS,
    MNEMONIC_VMASKMOVDQU,
    MNEMONIC_VMASKMOVPD,
    MNEMONIC_VMASKMOVPS,
    MNEMONIC_VMAXPD,
    MNEMONIC_VMAXPS,
    MNEMONIC_VMAXSD,
    MNEMONIC_VMAXSS,
    MNEMONIC_VMCALL,
    MNEMONIC_VMCLEAR,
    MNEMONIC_VMFUNC,
    MNEMONIC_VMINPD,
    MNEMONIC_VMINPS,
    MNEMONIC_VMINSD,
    MNEMONIC_VMINSS,
    MNEMONIC_VMLAUNCH,
    MNEMONIC_VMLOAD,
    MNEMONIC_VMMCALL,
    MNEMONIC_VMOVAPD,
    MNEMONIC_VMOVAPS,
    MNEMONIC_VMOVD,
    MNEMONIC_VMOVDDUP,
    MNEMONIC_VMOVDQA,
    MNEMONIC_VMOVDQA32,
    MNEMONIC_VMOVDQA64,
    MNEMONIC_VMOVDQU,
    MNEMONIC_VMOVDQU16,
    MNEMONIC_VMOVDQU32,
    MNEMONIC_VMOVDQU64,
    MNEMONIC_VMOVDQU8,
    MNEMONIC_VMOVHLPS,
    MNEMONIC_VMOVHPD,
    MNEMONIC_VMOVHPS,
    MNEMONIC_VMOVLHPS,
    MNEMONIC_VMOVLPD,
    MNEMONIC_VMOVLPS,
    MNEMONIC_VMOVMSKPD,
    MNEMONIC_VMOVMSKPS,
    MNEMONIC_VMOVNRAPD,
    MNEMONIC_VMOVNRAPS,
    MNEMONIC_VMOVNRNGOAPD,
    MNEMONIC_VMOVNRNGOAPS,
    MNEMONIC_VMOVNTDQ,
    MNEMONIC_VMOVNTDQA,
    MNEMONIC_VMOVNTPD,
    MNEMONIC_VMOVNTPS,
    MNEMONIC_VMOVQ,
    MNEMONIC_VMOVSD,
    MNEMONIC_VMOVSHDUP,
    MNEMONIC_VMOVSLDUP,
    MNEMONIC_VMOVSS,
    MNEMONIC_VMOVUPD,
    MNEMONIC_VMOVUPS,
    MNEMONIC_VMPSADBW,
    MNEMONIC_VMPTRLD,
    MNEMONIC_VMPTRST,
    MNEMONIC_VMREAD,
    MNEMONIC_VMRESUME,
    MNEMONIC_VMRUN,
    MNEMONIC_VMSAVE,
    MNEMONIC_VMULPD,
    MNEMONIC_VMULPS,
    MNEMONIC_VMULSD,
    MNEMONIC_VMULSS,
    MNEMONIC_VMWRITE,
    MNEMONIC_VMXOFF,
    MNEMONIC_VMXON,
    MNEMONIC_VORPD,
    MNEMONIC_VORPS,
    MNEMONIC_VP2INTERSECTD,
    MNEMONIC_VP2INTERSECTQ,
    MNEMONIC_VP4DPWSSD,
    MNEMONIC_VP4DPWSSDS,
    MNEMONIC_VPABSB,
    MNEMONIC_VPABSD,
    MNEMONIC_VPABSQ,
    MNEMONIC_VPABSW,
    MNEMONIC_VPACKSSDW,
    MNEMONIC_VPACKSSWB,
    MNEMONIC_VPACKSTOREHD,
    MNEMONIC_VPACKSTOREHPD,
    MNEMONIC_VPACKSTOREHPS,
    MNEMONIC_VPACKSTOREHQ,
    MNEMONIC_VPACKSTORELD,
    MNEMONIC_VPACKSTORELPD,
    MNEMONIC_VPACKSTORELPS,
    MNEMONIC_VPACKSTORELQ,
    MNEMONIC_VPACKUSDW,
    MNEMONIC_VPACKUSWB,
    MNEMONIC_VPADCD,
    MNEMONIC_VPADDB,
    MNEMONIC_VPADDD,
    MNEMONIC_VPADDQ,
    MNEMONIC_VPADDSB,
    MNEMONIC_VPADDSETCD,
    MNEMONIC_VPADDSETSD,
    MNEMONIC_VPADDSW,
    MNEMONIC_VPADDUSB,
    MNEMONIC_VPADDUSW,
    MNEMONIC_VPADDW,
    MNEMONIC_VPALIGNR,
    MNEMONIC_VPAND,
    MNEMONIC_VPANDD,
    MNEMONIC_VPANDN,
    MNEMONIC_VPANDND,
    MNEMONIC_VPANDNQ,
    MNEMONIC_VPANDQ,
    MNEMONIC_VPAVGB,
    MNEMONIC_VPAVGW,
    MNEMONIC_VPBLENDD,
    MNEMONIC_VPBLENDMB,
    MNEMONIC_VPBLENDMD,
    MNEMONIC_VPBLENDMQ,
    MNEMONIC_VPBLENDMW,
    MNEMONIC_VPBLENDVB,
    MNEMONIC_VPBLENDW,
    MNEMONIC_VPBROADCASTB,
    MNEMONIC_VPBROADCASTD,
    MNEMONIC_VPBROADCASTMB2Q,
    MNEMONIC_VPBROADCASTMW2D,
    MNEMONIC_VPBROADCASTQ,
    MNEMONIC_VPBROADCASTW,
    MNEMONIC_VPCLMULQDQ,
    MNEMONIC_VPCMOV,
    MNEMONIC_VPCMPB,
    MNEMONIC_VPCMPD,
    MNEMONIC_VPCMPEQB,
    MNEMONIC_VPCMPEQD,
    MNEMONIC_VPCMPEQQ,
    MNEMONIC_VPCMPEQW,
    MNEMONIC_VPCMPESTRI,
    MNEMONIC_VPCMPESTRM,
    MNEMONIC_VPCMPGTB,
    MNEMONIC_VPCMPGTD,
    MNEMONIC_VPCMPGTQ,
    MNEMONIC_VPCMPGTW,
    MNEMONIC_VPCMPISTRI,
    MNEMONIC_VPCMPISTRM,
    MNEMONIC_VPCMPLTD,
    MNEMONIC_VPCMPQ,
    MNEMONIC_VPCMPUB,
    MNEMONIC_VPCMPUD,
    MNEMONIC_VPCMPUQ,
    MNEMONIC_VPCMPUW,
    MNEMONIC_VPCMPW,
    MNEMONIC_VPCOMB,
    MNEMONIC_VPCOMD,
    MNEMONIC_VPCOMPRESSB,
    MNEMONIC_VPCOMPRESSD,
    MNEMONIC_VPCOMPRESSQ,
    MNEMONIC_VPCOMPRESSW,
    MNEMONIC_VPCOMQ,
    MNEMONIC_VPCOMUB,
    MNEMONIC_VPCOMUD,
    MNEMONIC_VPCOMUQ,
    MNEMONIC_VPCOMUW,
    MNEMONIC_VPCOMW,
    MNEMONIC_VPCONFLICTD,
    MNEMONIC_VPCONFLICTQ,
    MNEMONIC_VPDPBUSD,
    MNEMONIC_VPDPBUSDS,
    MNEMONIC_VPDPWSSD,
    MNEMONIC_VPDPWSSDS,
    MNEMONIC_VPERM2F128,
    MNEMONIC_VPERM2I128,
    MNEMONIC_VPERMB,
    MNEMONIC_VPERMD,
    MNEMONIC_VPERMF32X4,
    MNEMONIC_VPERMI2B,
    MNEMONIC_VPERMI2D,
    MNEMONIC_VPERMI2PD,
    MNEMONIC_VPERMI2PS,
    MNEMONIC_VPERMI2Q,
    MNEMONIC_VPERMI2W,
    MNEMONIC_VPERMIL2PD,
    MNEMONIC_VPERMIL2PS,
    MNEMONIC_VPERMILPD,
    MNEMONIC_VPERMILPS,
    MNEMONIC_VPERMPD,
    MNEMONIC_VPERMPS,
    MNEMONIC_VPERMQ,
    MNEMONIC_VPERMT2B,
    MNEMONIC_VPERMT2D,
    MNEMONIC_VPERMT2PD,
    MNEMONIC_VPERMT2PS,
    MNEMONIC_VPERMT2Q,
    MNEMONIC_VPERMT2W,
    MNEMONIC_VPERMW,
    MNEMONIC_VPEXPANDB,
    MNEMONIC_VPEXPANDD,
    MNEMONIC_VPEXPANDQ,
    MNEMONIC_VPEXPANDW,
    MNEMONIC_VPEXTRB,
    MNEMONIC_VPEXTRD,
    MNEMONIC_VPEXTRQ,
    MNEMONIC_VPEXTRW,
    MNEMONIC_VPGATHERDD,
    MNEMONIC_VPGATHERDQ,
    MNEMONIC_VPGATHERQD,
    MNEMONIC_VPGATHERQQ,
    MNEMONIC_VPHADDBD,
    MNEMONIC_VPHADDBQ,
    MNEMONIC_VPHADDBW,
    MNEMONIC_VPHADDD,
    MNEMONIC_VPHADDDQ,
    MNEMONIC_VPHADDSW,
    MNEMONIC_VPHADDUBD,
    MNEMONIC_VPHADDUBQ,
    MNEMONIC_VPHADDUBW,
    MNEMONIC_VPHADDUDQ,
    MNEMONIC_VPHADDUWD,
    MNEMONIC_VPHADDUWQ,
    MNEMONIC_VPHADDW,
    MNEMONIC_VPHADDWD,
    MNEMONIC_VPHADDWQ,
    MNEMONIC_VPHMINPOSUW,
    MNEMONIC_VPHSUBBW,
    MNEMONIC_VPHSUBD,
    MNEMONIC_VPHSUBDQ,
    MNEMONIC_VPHSUBSW,
    MNEMONIC_VPHSUBW,
    MNEMONIC_VPHSUBWD,
    MNEMONIC_VPINSRB,
    MNEMONIC_VPINSRD,
    MNEMONIC_VPINSRQ,
    MNEMONIC_VPINSRW,
    MNEMONIC_VPLZCNTD,
    MNEMONIC_VPLZCNTQ,
    MNEMONIC_VPMACSDD,
    MNEMONIC_VPMACSDQH,
    MNEMONIC_VPMACSDQL,
    MNEMONIC_VPMACSSDD,
    MNEMONIC_VPMACSSDQH,
    MNEMONIC_VPMACSSDQL,
    MNEMONIC_VPMACSSWD,
    MNEMONIC_VPMACSSWW,
    MNEMONIC_VPMACSWD,
    MNEMONIC_VPMACSWW,
    MNEMONIC_VPMADCSSWD,
    MNEMONIC_VPMADCSWD,
    MNEMONIC_VPMADD231D,
    MNEMONIC_VPMADD233D,
    MNEMONIC_VPMADD52HUQ,
    MNEMONIC_VPMADD52LUQ,
    MNEMONIC_VPMADDUBSW,
    MNEMONIC_VPMADDWD,
    MNEMONIC_VPMASKMOVD,
    MNEMONIC_VPMASKMOVQ,
    MNEMONIC_VPMAXSB,
    MNEMONIC_VPMAXSD,
    MNEMONIC_VPMAXSQ,
    MNEMONIC_VPMAXSW,
    MNEMONIC_VPMAXUB,
    MNEMONIC_VPMAXUD,
    MNEMONIC_VPMAXUQ,
    MNEMONIC_VPMAXUW,
    MNEMONIC_VPMINSB,
    MNEMONIC_VPMINSD,
    MNEMONIC_VPMINSQ,
    MNEMONIC_VPMINSW,
    MNEMONIC_VPMINUB,
    MNEMONIC_VPMINUD,
    MNEMONIC_VPMINUQ,
    MNEMONIC_VPMINUW,
    MNEMONIC_VPMOVB2M,
    MNEMONIC_VPMOVD2M,
    MNEMONIC_VPMOVDB,
    MNEMONIC_VPMOVDW,
    MNEMONIC_VPMOVM2B,
    MNEMONIC_VPMOVM2D,
    MNEMONIC_VPMOVM2Q,
    MNEMONIC_VPMOVM2W,
    MNEMONIC_VPMOVMSKB,
    MNEMONIC_VPMOVQ2M,
    MNEMONIC_VPMOVQB,
    MNEMONIC_VPMOVQD,
    MNEMONIC_VPMOVQW,
    MNEMONIC_VPMOVSDB,
    MNEMONIC_VPMOVSDW,
    MNEMONIC_VPMOVSQB,
    MNEMONIC_VPMOVSQD,
    MNEMONIC_VPMOVSQW,
    MNEMONIC_VPMOVSWB,
    MNEMONIC_VPMOVSXBD,
    MNEMONIC_VPMOVSXBQ,
    MNEMONIC_VPMOVSXBW,
    MNEMONIC_VPMOVSXDQ,
    MNEMONIC_VPMOVSXWD,
    MNEMONIC_VPMOVSXWQ,
    MNEMONIC_VPMOVUSDB,
    MNEMONIC_VPMOVUSDW,
    MNEMONIC_VPMOVUSQB,
    MNEMONIC_VPMOVUSQD,
    MNEMONIC_VPMOVUSQW,
    MNEMONIC_VPMOVUSWB,
    MNEMONIC_VPMOVW2M,
    MNEMONIC_VPMOVWB,
    MNEMONIC_VPMOVZXBD,
    MNEMONIC_VPMOVZXBQ,
    MNEMONIC_VPMOVZXBW,
    MNEMONIC_VPMOVZXDQ,
    MNEMONIC_VPMOVZXWD,
    MNEMONIC_VPMOVZXWQ,
    MNEMONIC_VPMULDQ,
    MNEMONIC_VPMULHD,
    MNEMONIC_VPMULHRSW,
    MNEMONIC_VPMULHUD,
    MNEMONIC_VPMULHUW,
    MNEMONIC_VPMULHW,
    MNEMONIC_VPMULLD,
    MNEMONIC_VPMULLQ,
    MNEMONIC_VPMULLW,
    MNEMONIC_VPMULTISHIFTQB,
    MNEMONIC_VPMULUDQ,
    MNEMONIC_VPOPCNTB,
    MNEMONIC_VPOPCNTD,
    MNEMONIC_VPOPCNTQ,
    MNEMONIC_VPOPCNTW,
    MNEMONIC_VPOR,
    MNEMONIC_VPORD,
    MNEMONIC_VPORQ,
    MNEMONIC_VPPERM,
    MNEMONIC_VPREFETCH0,
    MNEMONIC_VPREFETCH1,
    MNEMONIC_VPREFETCH2,
    MNEMONIC_VPREFETCHE0,
    MNEMONIC_VPREFETCHE1,
    MNEMONIC_VPREFETCHE2,
    MNEMONIC_VPREFETCHENTA,
    MNEMONIC_VPREFETCHNTA,
    MNEMONIC_VPROLD,
    MNEMONIC_VPROLQ,
    MNEMONIC_VPROLVD,
    MNEMONIC_VPROLVQ,
    MNEMONIC_VPRORD,
    MNEMONIC_VPRORQ,
    MNEMONIC_VPRORVD,
    MNEMONIC_VPRORVQ,
    MNEMONIC_VPROTB,
    MNEMONIC_VPROTD,
    MNEMONIC_VPROTQ,
    MNEMONIC_VPROTW,
    MNEMONIC_VPSADBW,
    MNEMONIC_VPSBBD,
    MNEMONIC_VPSBBRD,
    MNEMONIC_VPSCATTERDD,
    MNEMONIC_VPSCATTERDQ,
    MNEMONIC_VPSCATTERQD,
    MNEMONIC_VPSCATTERQQ,
    MNEMONIC_VPSHAB,
    MNEMONIC_VPSHAD,
    MNEMONIC_VPSHAQ,
    MNEMONIC_VPSHAW,
    MNEMONIC_VPSHLB,
    MNEMONIC_VPSHLD,
    MNEMONIC_VPSHLDD,
    MNEMONIC_VPSHLDQ,
    MNEMONIC_VPSHLDVD,
    MNEMONIC_VPSHLDVQ,
    MNEMONIC_VPSHLDVW,
    MNEMONIC_VPSHLDW,
    MNEMONIC_VPSHLQ,
    MNEMONIC_VPSHLW,
    MNEMONIC_VPSHRDD,
    MNEMONIC_VPSHRDQ,
    MNEMONIC_VPSHRDVD,
    MNEMONIC_VPSHRDVQ,
    MNEMONIC_VPSHRDVW,
    MNEMONIC_VPSHRDW,
    MNEMONIC_VPSHUFB,
    MNEMONIC_VPSHUFBITQMB,
    MNEMONIC_VPSHUFD,
    MNEMONIC_VPSHUFHW,
    MNEMONIC_VPSHUFLW,
    MNEMONIC_VPSIGNB,
    MNEMONIC_VPSIGND,
    MNEMONIC_VPSIGNW,
    MNEMONIC_VPSLLD,
    MNEMONIC_VPSLLDQ,
    MNEMONIC_VPSLLQ,
    MNEMONIC_VPSLLVD,
    MNEMONIC_VPSLLVQ,
    MNEMONIC_VPSLLVW,
    MNEMONIC_VPSLLW,
    MNEMONIC_VPSRAD,
    MNEMONIC_VPSRAQ,
    MNEMONIC_VPSRAVD,
    MNEMONIC_VPSRAVQ,
    MNEMONIC_VPSRAVW,
    MNEMONIC_VPSRAW,
    MNEMONIC_VPSRLD,
    MNEMONIC_VPSRLDQ,
    MNEMONIC_VPSRLQ,
    MNEMONIC_VPSRLVD,
    MNEMONIC_VPSRLVQ,
    MNEMONIC_VPSRLVW,
    MNEMONIC_VPSRLW,
    MNEMONIC_VPSUBB,
    MNEMONIC_VPSUBD,
    MNEMONIC_VPSUBQ,
    MNEMONIC_VPSUBRD,
    MNEMONIC_VPSUBRSETBD,
    MNEMONIC_VPSUBSB,
    MNEMONIC_VPSUBSETBD,
    MNEMONIC_VPSUBSW,
    MNEMONIC_VPSUBUSB,
    MNEMONIC_VPSUBUSW,
    MNEMONIC_VPSUBW,
    MNEMONIC_VPTERNLOGD,
    MNEMONIC_VPTERNLOGQ,
    MNEMONIC_VPTEST,
    MNEMONIC_VPTESTMB,
    MNEMONIC_VPTESTMD,
    MNEMONIC_VPTESTMQ,
    MNEMONIC_VPTESTMW,
    MNEMONIC_VPTESTNMB,
    MNEMONIC_VPTESTNMD,
    MNEMONIC_VPTESTNMQ,
    MNEMONIC_VPTESTNMW,
    MNEMONIC_VPUNPCKHBW,
    MNEMONIC_VPUNPCKHDQ,
    MNEMONIC_VPUNPCKHQDQ,
    MNEMONIC_VPUNPCKHWD,
    MNEMONIC_VPUNPCKLBW,
    MNEMONIC_VPUNPCKLDQ,
    MNEMONIC_VPUNPCKLQDQ,
    MNEMONIC_VPUNPCKLWD,
    MNEMONIC_VPXOR,
    MNEMONIC_VPXORD,
    MNEMONIC_VPXORQ,
    MNEMONIC_VRANGEPD,
    MNEMONIC_VRANGEPS,
    MNEMONIC_VRANGESD,
    MNEMONIC_VRANGESS,
    MNEMONIC_VRCP14PD,
    MNEMONIC_VRCP14PS,
    MNEMONIC_VRCP14SD,
    MNEMONIC_VRCP14SS,
    MNEMONIC_VRCP23PS,
    MNEMONIC_VRCP28PD,
    MNEMONIC_VRCP28PS,
    MNEMONIC_VRCP28SD,
    MNEMONIC_VRCP28SS,
    MNEMONIC_VRCPPS,
    MNEMONIC_VRCPSS,
    MNEMONIC_VREDUCEPD,
    MNEMONIC_VREDUCEPS,
    MNEMONIC_VREDUCESD,
    MNEMONIC_VREDUCESS,
    MNEMONIC_VRNDFXPNTPD,
    MNEMONIC_VRNDFXPNTPS,
    MNEMONIC_VRNDSCALEPD,
    MNEMONIC_VRNDSCALEPS,
    MNEMONIC_VRNDSCALESD,
    MNEMONIC_VRNDSCALESS,
    MNEMONIC_VROUNDPD,
    MNEMONIC_VROUNDPS,
    MNEMONIC_VROUNDSD,
    MNEMONIC_VROUNDSS,
    MNEMONIC_VRSQRT14PD,
    MNEMONIC_VRSQRT14PS,
    MNEMONIC_VRSQRT14SD,
    MNEMONIC_VRSQRT14SS,
    MNEMONIC_VRSQRT23PS,
    MNEMONIC_VRSQRT28PD,
    MNEMONIC_VRSQRT28PS,
    MNEMONIC_VRSQRT28SD,
    MNEMONIC_VRSQRT28SS,
    MNEMONIC_VRSQRTPS,
    MNEMONIC_VRSQRTSS,
    MNEMONIC_VSCALEFPD,
    MNEMONIC_VSCALEFPS,
    MNEMONIC_VSCALEFSD,
    MNEMONIC_VSCALEFSS,
    MNEMONIC_VSCALEPS,
    MNEMONIC_VSCATTERDPD,
    MNEMONIC_VSCATTERDPS,
    MNEMONIC_VSCATTERPF0DPD,
    MNEMONIC_VSCATTERPF0DPS,
    MNEMONIC_VSCATTERPF0HINTDPD,
    MNEMONIC_VSCATTERPF0HINTDPS,
    MNEMONIC_VSCATTERPF0QPD,
    MNEMONIC_VSCATTERPF0QPS,
    MNEMONIC_VSCATTERPF1DPD,
    MNEMONIC_VSCATTERPF1DPS,
    MNEMONIC_VSCATTERPF1QPD,
    MNEMONIC_VSCATTERPF1QPS,
    MNEMONIC_VSCATTERQPD,
    MNEMONIC_VSCATTERQPS,
    MNEMONIC_VSHUFF32X4,
    MNEMONIC_VSHUFF64X2,
    MNEMONIC_VSHUFI32X4,
    MNEMONIC_VSHUFI64X2,
    MNEMONIC_VSHUFPD,
    MNEMONIC_VSHUFPS,
    MNEMONIC_VSQRTPD,
    MNEMONIC_VSQRTPS,
    MNEMONIC_VSQRTSD,
    MNEMONIC_VSQRTSS,
    MNEMONIC_VSTMXCSR,
    MNEMONIC_VSUBPD,
    MNEMONIC_VSUBPS,
    MNEMONIC_VSUBRPD,
    MNEMONIC_VSUBRPS,
    MNEMONIC_VSUBSD,
    MNEMONIC_VSUBSS,
    MNEMONIC_VTESTPD,
    MNEMONIC_VTESTPS,
    MNEMONIC_VUCOMISD,
    MNEMONIC_VUCOMISS,
    MNEMONIC_VUNPCKHPD,
    MNEMONIC_VUNPCKHPS,
    MNEMONIC_VUNPCKLPD,
    MNEMONIC_VUNPCKLPS,
    MNEMONIC_VXORPD,
    MNEMONIC_VXORPS,
    MNEMONIC_VZEROALL,
    MNEMONIC_VZEROUPPER,
    MNEMONIC_WBINVD,
    MNEMONIC_WRFSBASE,
    MNEMONIC_WRGSBASE,
    MNEMONIC_WRMSR,
    MNEMONIC_WRPKRU,
    MNEMONIC_WRSSD,
    MNEMONIC_WRSSQ,
    MNEMONIC_WRUSSD,
    MNEMONIC_WRUSSQ,
    MNEMONIC_XABORT,
    MNEMONIC_XADD,
    MNEMONIC_XBEGIN,
    MNEMONIC_XCHG,
    MNEMONIC_XCRYPT_CBC,
    MNEMONIC_XCRYPT_CFB,
    MNEMONIC_XCRYPT_CTR,
    MNEMONIC_XCRYPT_ECB,
    MNEMONIC_XCRYPT_OFB,
    MNEMONIC_XEND,
    MNEMONIC_XGETBV,
    MNEMONIC_XLAT,
    MNEMONIC_XOR,
    MNEMONIC_XORPD,
    MNEMONIC_XORPS,
    MNEMONIC_XRESLDTRK,
    MNEMONIC_XRSTOR,
    MNEMONIC_XRSTOR64,
    MNEMONIC_XRSTORS,
    MNEMONIC_XRSTORS64,
    MNEMONIC_XSAVE,
    MNEMONIC_XSAVE64,
    MNEMONIC_XSAVEC,
    MNEMONIC_XSAVEC64,
    MNEMONIC_XSAVEOPT,
    MNEMONIC_XSAVEOPT64,
    MNEMONIC_XSAVES,
    MNEMONIC_XSAVES64,
    MNEMONIC_XSETBV,
    MNEMONIC_XSHA1,
    MNEMONIC_XSHA256,
    MNEMONIC_XSTORE,
    MNEMONIC_XSUSLDTRK,
    MNEMONIC_XTEST,
    MNEMONIC_UNKNOWN = -1,

    // Aliases
    MNEMONIC_JA = MNEMONIC_JNBE,
    MNEMONIC_JAE = MNEMONIC_JNB,
    MNEMONIC_JNC = MNEMONIC_JNB,
    MNEMONIC_JC = MNEMONIC_JB,
    MNEMONIC_JNAE = MNEMONIC_JB,
    MNEMONIC_JE = MNEMONIC_JZ,
    MNEMONIC_JNE = MNEMONIC_JNZ,
    MNEMONIC_JNA = MNEMONIC_JBE,
    MNEMONIC_JPE = MNEMONIC_JP,
    MNEMONIC_JPO = MNEMONIC_JNP,
    MNEMONIC_JGE = MNEMONIC_JNL,
    MNEMONIC_JNG = MNEMONIC_JLE,
    MNEMONIC_JG = MNEMONIC_JNLE,
};

/*
 * Registers.
 */
enum Register : uint8_t
{
    REGISTER_NONE,
    REGISTER_FLAGS,     // Pseudo-register

    REGISTER_AH,
    REGISTER_CH,
    REGISTER_DH,
    REGISTER_BH,
    
    REGISTER_AL,
    REGISTER_CL,
    REGISTER_DL,
    REGISTER_BL,
    REGISTER_SPL,
    REGISTER_BPL,
    REGISTER_SIL,
    REGISTER_DIL,
    REGISTER_R8B,
    REGISTER_R9B,
    REGISTER_R10B,
    REGISTER_R11B,
    REGISTER_R12B,
    REGISTER_R13B,
    REGISTER_R14B,
    REGISTER_R15B,
    
    REGISTER_AX,
    REGISTER_CX,
    REGISTER_DX,
    REGISTER_BX,
    REGISTER_SP,
    REGISTER_BP,
    REGISTER_SI,
    REGISTER_DI,
    REGISTER_R8W,
    REGISTER_R9W,
    REGISTER_R10W,
    REGISTER_R11W,
    REGISTER_R12W,
    REGISTER_R13W,
    REGISTER_R14W,
    REGISTER_R15W,
    
    REGISTER_RFLAGS,
    REGISTER_IP,
    
    REGISTER_EAX,
    REGISTER_ECX,
    REGISTER_EDX,
    REGISTER_EBX,
    REGISTER_ESP,
    REGISTER_EBP,
    REGISTER_ESI,
    REGISTER_EDI,
    REGISTER_R8D,
    REGISTER_R9D,
    REGISTER_R10D,
    REGISTER_R11D,
    REGISTER_R12D,
    REGISTER_R13D,
    REGISTER_R14D,
    REGISTER_R15D,
    
    REGISTER_EIP,
    
    REGISTER_RAX,
    REGISTER_RCX,
    REGISTER_RDX,
    REGISTER_RBX,
    REGISTER_RSP,
    REGISTER_RBP,
    REGISTER_RSI,
    REGISTER_RDI,
    REGISTER_R8,
    REGISTER_R9,
    REGISTER_R10,
    REGISTER_R11,
    REGISTER_R12,
    REGISTER_R13,
    REGISTER_R14,
    REGISTER_R15,
    
    REGISTER_RIP,
    
    REGISTER_XMM0,
    REGISTER_XMM1,
    REGISTER_XMM2,
    REGISTER_XMM3,
    REGISTER_XMM4,
    REGISTER_XMM5,
    REGISTER_XMM6,
    REGISTER_XMM7,
    REGISTER_XMM8,
    REGISTER_XMM9,
    REGISTER_XMM10,
    REGISTER_XMM11,
    REGISTER_XMM12,
    REGISTER_XMM13,
    REGISTER_XMM14,
    REGISTER_XMM15,
    REGISTER_XMM16,
    REGISTER_XMM17,
    REGISTER_XMM18,
    REGISTER_XMM19,
    REGISTER_XMM20,
    REGISTER_XMM21,
    REGISTER_XMM22,
    REGISTER_XMM23,
    REGISTER_XMM24,
    REGISTER_XMM25,
    REGISTER_XMM26,
    REGISTER_XMM27,
    REGISTER_XMM28,
    REGISTER_XMM29,
    REGISTER_XMM30,
    REGISTER_XMM31,
    
    REGISTER_YMM0,
    REGISTER_YMM1,
    REGISTER_YMM2,
    REGISTER_YMM3,
    REGISTER_YMM4,
    REGISTER_YMM5,
    REGISTER_YMM6,
    REGISTER_YMM7,
    REGISTER_YMM8,
    REGISTER_YMM9,
    REGISTER_YMM10,
    REGISTER_YMM11,
    REGISTER_YMM12,
    REGISTER_YMM13,
    REGISTER_YMM14,
    REGISTER_YMM15,
    REGISTER_YMM16,
    REGISTER_YMM17,
    REGISTER_YMM18,
    REGISTER_YMM19,
    REGISTER_YMM20,
    REGISTER_YMM21,
    REGISTER_YMM22,
    REGISTER_YMM23,
    REGISTER_YMM24,
    REGISTER_YMM25,
    REGISTER_YMM26,
    REGISTER_YMM27,
    REGISTER_YMM28,
    REGISTER_YMM29,
    REGISTER_YMM30,
    REGISTER_YMM31,
    
    REGISTER_ZMM0,
    REGISTER_ZMM1,
    REGISTER_ZMM2,
    REGISTER_ZMM3,
    REGISTER_ZMM4,
    REGISTER_ZMM5,
    REGISTER_ZMM6,
    REGISTER_ZMM7,
    REGISTER_ZMM8,
    REGISTER_ZMM9,
    REGISTER_ZMM10,
    REGISTER_ZMM11,
    REGISTER_ZMM12,
    REGISTER_ZMM13,
    REGISTER_ZMM14,
    REGISTER_ZMM15,
    REGISTER_ZMM16,
    REGISTER_ZMM17,
    REGISTER_ZMM18,
    REGISTER_ZMM19,
    REGISTER_ZMM20,
    REGISTER_ZMM21,
    REGISTER_ZMM22,
    REGISTER_ZMM23,
    REGISTER_ZMM24,
    REGISTER_ZMM25,
    REGISTER_ZMM26,
    REGISTER_ZMM27,
    REGISTER_ZMM28,
    REGISTER_ZMM29,
    REGISTER_ZMM30,
    REGISTER_ZMM31,
    
    REGISTER_ES,
    REGISTER_CS,
    REGISTER_SS,
    REGISTER_DS,
    REGISTER_FS,
    REGISTER_GS,
    
    REGISTER_CR0,
    REGISTER_CR1,
    REGISTER_CR2,
    REGISTER_CR3,
    REGISTER_CR4,
    REGISTER_CR5,
    REGISTER_CR6,
    REGISTER_CR7,
    REGISTER_CR8,
    REGISTER_CR9,
    REGISTER_CR10,
    REGISTER_CR11,
    REGISTER_CR12,
    REGISTER_CR13,
    REGISTER_CR14,
    REGISTER_CR15,
    
    REGISTER_DR0,
    REGISTER_DR1,
    REGISTER_DR2,
    REGISTER_DR3,
    REGISTER_DR4,
    REGISTER_DR5,
    REGISTER_DR6,
    REGISTER_DR7,
    REGISTER_DR8,
    REGISTER_DR9,
    REGISTER_DR10,
    REGISTER_DR11,
    REGISTER_DR12,
    REGISTER_DR13,
    REGISTER_DR14,
    REGISTER_DR15,
    
    REGISTER_K0,
    REGISTER_K1,
    REGISTER_K2,
    REGISTER_K3,
    REGISTER_K4,
    REGISTER_K5,
    REGISTER_K6,
    REGISTER_K7,
    
    REGISTER_MM0,
    REGISTER_MM1,
    REGISTER_MM2,
    REGISTER_MM3,
    REGISTER_MM4,
    REGISTER_MM5,
    REGISTER_MM6,
    REGISTER_MM7,
    
    REGISTER_ST0,
    REGISTER_ST1,
    REGISTER_ST2,
    REGISTER_ST3,
    REGISTER_ST4,
    REGISTER_ST5,
    REGISTER_ST6,
    REGISTER_ST7,

    REGISTER_INVALID,
};

/*
 * Types.
 */
typedef uint8_t Type;

#define TYPE_NONE                   0x00
#define TYPE_CHAR                   0x01
#define TYPE_INT8                   0x02
#define TYPE_INT16                  0x03
#define TYPE_INT32                  0x04
#define TYPE_INT64                  0x05
#define TYPE_VOID                   0x06
#define TYPE_NULL_PTR               0x07
#define TYPE_PTR                    0x10
#define TYPE_PTR_PTR                0x20
#define TYPE_CONST                  0x40

#define TYPE_VOID_PTR               (TYPE_VOID | TYPE_PTR)
#define TYPE_CONST_VOID_PTR         (TYPE_CONST | TYPE_VOID | TYPE_PTR)
#define TYPE_CONST_CHAR_PTR         (TYPE_CONST | TYPE_CHAR | TYPE_PTR)
#define TYPE_CONST_INT8_PTR         (TYPE_CONST | TYPE_INT8 | TYPE_PTR)

/*
 * Instruction categories.
 */
#define CATEGORY_RETURN         0x0001
#define CATEGORY_CALL           0x0002
#define CATEGORY_JUMP           0x0004
#define CATEGORY_CONDITIONAL    0x0008
#define CATEGORY_X87            0x0010
#define CATEGORY_MMX            0x0020
#define CATEGORY_SSE            0x0040
#define CATEGORY_AVX            0x0080
#define CATEGORY_AVX2           0x0100
#define CATEGORY_AVX512         0x0200

/*
 * Operands.
 */
enum OpType : int8_t
{
    OPTYPE_IMM,                     // Immediate operand
    OPTYPE_REG,                     // Register operand
    OPTYPE_MEM,                     // Memory operand
    OPTYPE_INVALID = -1
};
typedef unsigned Access;
#define ACCESS_READ             0x01
#define ACCESS_WRITE            0x02
struct MemOpInfo
{
    int32_t disp;                   // Displacement
    Register seg;                   // Segment register
    Register base;                  // Base register
    Register index;                 // Index register
    uint8_t scale;                  // Scale
};
struct OpInfo
{
    OpType type;                    // Operand type
    uint8_t size;                   // Operand size
    Access access;                  // Operand access
    union
    {
        int64_t imm;                // Immediate operand value
        Register reg;               // Register operand value
        MemOpInfo mem;              // Memory operand value
    };
};

/*
 * Flags.
 */
#define FLAG_CF                 0x01
#define FLAG_PF                 0x02
#define FLAG_AF                 0x04
#define FLAG_ZF                 0x08
#define FLAG_SF                 0x10
#define FLAG_OF                 0x20
#define FLAG_ALL                \
    (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)

/*
 * Compressed instruction representation.
 * Use getInstrInfo() for more detailed information.
 */
struct Instr
{
    size_t offset:40;               // Instruction offset in file
    size_t matching:24;             // (E9Tool internal)

    size_t address:48;              // Instruction address
    size_t size:4;                  // Instruction size
    
    size_t data:1;                  // (E9Tool internal)
    size_t patch:1;                 // (E9Tool internal)
    size_t emit:1;                  // (E9Tool internal)
    size_t sus:1;                   // (E9Tool internal)
    size_t first:1;                 // (E9Tool internal)

    Instr() : patch(0), emit(0), matching(0), sus(0), first(0)
    {
        ;
    }
};

/*
 * Decompressed instruction representation.
 */
struct InstrInfo
{
    const Instr    *instr;          // Original uncompressed instruction
    const void     *raw;            // Raw instruction, or nullptr.
    const uint8_t  *data;           // Instruction bytes
    intptr_t        address;        // Instruction address
    off_t           offset;         // Instruction file offset
    Mnemonic        mnemonic;       // Instruction mnemonic enum
    uint16_t        category;       // Instruction category
    uint8_t         size;           // Instruction size
    bool            relative;       // Imm/disp used for relative address?
    struct
    {
        struct
        {
            int8_t  disp;           // Instruction displacement size, or -1
            int8_t  imm;            // Instruction immediate size, or -1
        } size;
        struct
        {
            int8_t  rex;            // Instruction rex offset, or -1
            int8_t  vex;            // Instruction vex offset, or -1
            int8_t  evex;           // Instruction evex offset, or -1
            uint8_t opcode;         // Instruction opcode offset
            int8_t  modrm;          // Instruction ModR/M offset, or -1
            int8_t  sib;            // Instruction SIB offset, or -1
            int8_t  disp;           // Instruction displacement offset, or -1
            int8_t  imm;            // Instruction immediate offset, or -1
        } offset;
    } encoding;
    struct
    {
        Register    read[16];       // Instruction register reads
        Register    write[16];      // Instruction register writes
        Register    condread[16];   // Instruction register conditional reads
        Register    condwrite[16];  // Instruction register conditional writes
    } regs;
    struct
    {
        uint8_t     read;           // Instruction flags read from
        uint8_t     write;          // Instruction flags written to
    } flags;
    struct
    {
        uint8_t     op;             // Number of operands
    } count;
    OpInfo          op[8];          // Instruction operands
    struct
    {
        const char *section;        // Instruction section
        const char *mnemonic;       // Instruction mnemonic string
        char        instr[64];      // Instruction string
    } string;

    /*
     * Helper functions.
     */
    bool hasREX() const
    {
        return (encoding.offset.rex >= 0);
    }
    bool hasVEX() const
    {
        return (encoding.offset.vex >= 0);
    }
    bool hasEVEX() const
    {
        return (encoding.offset.evex >= 0);
    }
    bool hasMODRM() const
    {
        return (encoding.offset.modrm >= 0);
    }
    bool hasSIB() const
    {
        return (encoding.offset.sib >= 0);
    }
    bool hasDISP() const
    {
        return (encoding.offset.disp >= 0);
    }
    bool hasIMM() const
    {
        return (encoding.offset.imm >= 0);
    }
    uint8_t getREX() const
    {
        return (hasREX()? data[encoding.offset.rex]: 0);
    }
    uint32_t getVEX() const
    {
        return (hasVEX()? (data[encoding.offset.vex] == 0xC5?
                *(uint16_t *)(data + encoding.offset.vex):
                (*(uint32_t *)(data + encoding.offset.vex)) & 0xFFFFFF): 0);
    }
    uint32_t getEVEX() const
    {
        return (hasEVEX()? *(uint32_t *)(data + encoding.offset.evex): 0);
    }
    uint8_t getMODRM() const
    {
        return (hasMODRM()? data[encoding.offset.modrm]: 0);
    }
    uint8_t getSIB() const
    {
        return (hasSIB()? data[encoding.offset.sib]: 0);
    }
    int32_t getDISP() const
    {
        switch (encoding.size.disp)
        {
            case sizeof(int8_t):
                return (int32_t)*(int8_t *)(data + encoding.offset.disp);
            case sizeof(int32_t):
                return *(int32_t *)(data + encoding.offset.disp);
            default:
                return 0;
        }
    }
    int64_t getIMM() const
    {
        switch (encoding.size.imm)
        {
            case sizeof(int8_t):
                return (int64_t)*(int8_t *)(data + encoding.offset.imm);
            case sizeof(int16_t):
                return (int64_t)*(int16_t *)(data + encoding.offset.imm);
            case sizeof(int32_t):
                return (int64_t)*(int32_t *)(data + encoding.offset.imm);
            case sizeof(int64_t):
                return *(int64_t *)(data + encoding.offset.imm);
            default:
                return 0;
        }
    }
};

/*
 * Argument fields.
 */
enum FieldKind : uint8_t
{
    FIELD_NONE,                     // No field.
    FIELD_DISPL,                    // Displacement.
    FIELD_BASE,                     // Base register.
    FIELD_INDEX,                    // Index register.
    FIELD_SCALE,                    // Scale.
    FIELD_TYPE,                     // Type.
    FIELD_ACCESS,                   // Access.
    FIELD_SIZE,                     // Size.
    FIELD_ADDR,                     // Address.
    FIELD_OFFSET,                   // Offset.
    FIELD_LEN,                      // Length.
    FIELD_NAME,                     // Name.
};

/*
 * Memory operand seg:disp(base,index,scale)
 */
struct MemOp
{
    int32_t disp;                   // Displacement
    Register seg;                   // Segment register
    Register base;                  // Base register
    Register index;                 // Index register
    uint8_t scale;                  // Scale
    uint8_t size;                   // Size
};

/*
 * Argument kinds.
 */
enum ArgumentKind : uint8_t
{
    ARGUMENT_INVALID,               // Invalid argument
    ARGUMENT_CSV,                   // CSV file data argument
    ARGUMENT_INTEGER,               // Constant integer argument
    ARGUMENT_STRING,                // Constant string argument
    ARGUMENT_ID,                    // Patch ID
    ARGUMENT_OFFSET,                // Instruction file offset
    ARGUMENT_ADDR,                  // Instruction address
    ARGUMENT_NEXT,                  // Next instruction address
    ARGUMENT_BASE,                  // Base address of ELF binary in memory
    ARGUMENT_ASM,                   // Assembly string
    ARGUMENT_ASM_SIZE,              // Assembly string size
    ARGUMENT_ASM_LEN,               // Assembly string length
    ARGUMENT_BYTES,                 // Instruction bytes
    ARGUMENT_BYTES_SIZE,            // Instruction bytes size
    ARGUMENT_TARGET,                // Call/jump target
    ARGUMENT_TRAMPOLINE,            // Trampoline
    ARGUMENT_RANDOM,                // Random number
    ARGUMENT_REGISTER,              // Register
    ARGUMENT_MEMOP,                 // Memory operand
    ARGUMENT_STATE,                 // The complete GPR state
    ARGUMENT_SYMBOL,                // Symbol value argument
    ARGUMENT_CONFIG,                // Pointer to the e9_config_s struct
    ARGUMENT_NULL,                  // NULL pointer argument

    ARGUMENT_FILENAME,              // Filename (relative)
    ARGUMENT_ABSNAME,               // Absolute filename
    ARGUMENT_BASENAME,              // Basename
    ARGUMENT_DIRNAME,               // Directory name
    ARGUMENT_LINE,                  // Line #

    ARGUMENT_BB,                    // Basic block
    ARGUMENT_F,                     // Function

    ARGUMENT_OP,                    // Operand[i]
    ARGUMENT_SRC,                   // Source operand[i]
    ARGUMENT_DST,                   // Dest operand[i]
    ARGUMENT_IMM,                   // Immediate operand[i]
    ARGUMENT_REG,                   // Register operand[i]
    ARGUMENT_MEM,                   // Memory operand[i]

    ARGUMENT_REX,                   // Rex prefix byte
    ARGUMENT_MODRM,                 // ModRM byte
    ARGUMENT_SIB,                   // SIB byte
    ARGUMENT_DISP8,                 // 8-bit displacement
    ARGUMENT_DISP32,                // 32-bit displacement
    ARGUMENT_IMM8,                  // 8-bit displacement
    ARGUMENT_IMM32,                 // 32-bit displacement

    ARGUMENT_MAX                    // Maximum argument value
};

/*
 * Argument.
 */
struct Argument
{
    ArgumentKind kind;              // Argument kind.
    FieldKind field;                // Argument field.
    bool ptr;                       // Argument is passed by pointer?
    bool end;                       // Argument ptr to the end of object?
    bool _static;                   // Argument is static?
    bool duplicate;                 // Argument is a duplicate?
    Type cast;                      // Argument type cast.
    intptr_t value;                 // Argument value.
    MemOp memop;                    // Argument memop value.
    const char *name;               // Argument name
                                    // (ARGUMENT_CSV/STRING/SYMBOL).
};

/*
 * Call trampoline object.
 */
struct Call;

/*
 * CFG information.
 */
typedef uint8_t TargetKind;
#define TARGET_DIRECT   0x01        // Direct call/jump
#define TARGET_INDIRECT 0x02        // Indirect call/jump
#define TARGET_FUNCTION 0x04        // Target is called
typedef std::map<intptr_t, TargetKind> Targets;

struct BB
{
    const uint32_t lb;              // Entry instruction index
    const uint32_t ub;              // Exit instruction index
    const uint32_t best;            // Best instruction to instrument

    BB(uint32_t lb, uint32_t ub, uint32_t best) :
        lb(lb), ub(ub), best(best)
    {
        ;
    }
};
typedef std::vector<BB> BBs;

struct F
{
    const char * const name;        // Function name (or nullptr if no name).
    const uint32_t lb;              // Entry instruction index
    const uint32_t ub;              // Last instruction index
    const uint32_t best;            // Best instruction to instrument

    F(const char *name, uint32_t lb, uint32_t ub, uint32_t best) :
        name(name), lb(lb), ub(ub), best(best)
    {
        ;
    }
};
typedef std::vector<F> Fs;

struct Line
{
    const intptr_t lb;                  // Line base address
    const intptr_t ub;                  // Line end address
    const char * const dir;             // Line directory
    const char * const file;            // Line filename
    const unsigned line;                // Line number

    Line(intptr_t lb, intptr_t ub, const char *dir, const char *file,
            unsigned line) :
        lb(lb), ub(ub), dir(dir), file(file), line(line)
    {
        ;
    }
};
typedef std::map<intptr_t, Line> Lines;

/*
 * Low-level functions that send fragments of JSONRPC messages:
 */
extern void sendMessageHeader(FILE *out, const char *method);
extern unsigned sendMessageFooter(FILE *out, bool sync = false);
extern void sendParamHeader(FILE *out, const char *name);
extern void sendSeparator(FILE *out, bool last = false);
extern void sendMetadataHeader(FILE *out);
extern void sendMetadataFooter(FILE *out);
extern void sendDefinitionHeader(FILE *out, const char *patch,
    const char *name);
extern void sendDefinitionFooter(FILE *out, bool last = false);
extern void sendInteger(FILE *out, intptr_t i);
extern void sendString(FILE *out, const char *s);
extern void sendCode(FILE *out, const char *code);
extern void sendBytes(FILE *out, const uint8_t *bytes, size_t len);

/*
 * High-level functions that send complete E9PATCH JSONRPC messages:
 */
extern unsigned sendBinaryMessage(FILE *out, const char *mode,
    const char *filename);
extern unsigned sendOptionsMessage(FILE *out, std::vector<const char *> &argv);
extern unsigned sendReserveMessage(FILE *out, intptr_t addr, size_t len,
    bool absolute = false);
extern unsigned sendReserveMessage(FILE *out, intptr_t addr,
    const uint8_t *data, size_t len, int prot, intptr_t init = 0x0,
    intptr_t fini = 0x0, intptr_t mmap = 0x0, bool absolute = false,
    const uint8_t *preinit = nullptr, size_t preinit_len = 0,
    const uint8_t *postinit = nullptr, size_t postinit_len = 0);
extern void sendELFFileMessage(FILE *out, const ELF *elf,
    bool absolute = false);
extern unsigned sendEmptyTrampolineMessage(FILE *out);
extern unsigned sendTrapTrampolineMessage(FILE *out);
extern unsigned sendPrintTrampolineMessage(FILE *out, BinaryType type);
extern unsigned sendExitTrampolineMessage(FILE *out, BinaryType type,
    int status);
extern unsigned sendSignalTrampolineMessage(FILE *out, BinaryType type,
    int sig);
extern unsigned sendCallTrampolineMessage(FILE *out, const char *name,
    const Call &call);
extern unsigned sendTrampolineMessage(FILE *out, const char *name,
    const char *template_);
extern unsigned sendInstructionMessage(FILE *out, intptr_t addr, size_t size,
    off_t offset);
extern unsigned sendEmitMessage(FILE *out, const char *filename,
    const char *format);
extern void sendPrintMetadata(FILE *out, const InstrInfo *info);
extern void sendCallMetadata(FILE *out, const char *name, const ELF *elf,
    const Call &call, const std::vector<Argument> &args,
    intptr_t id, const std::vector<Instr> &Is, size_t idx,
    const InstrInfo *info);

/*
 * ELF functions.
 */
extern ELF *parseELF(const char *filename, intptr_t base = 0x0);
extern ELF *parsePE(const char *filename);  // See note
extern ELF *parseBinary(const char *filename, intptr_t base = 0x0);
extern void freeELF(ELF *elf);
extern BinaryType getELFType(const ELF *elf);
extern const char *getELFFilename(const ELF *elf);
extern const uint8_t *getELFData(const ELF *elf);
extern size_t getELFDataSize(const ELF *elf);
extern intptr_t getELFBaseAddr(const ELF *elf);
extern intptr_t getELFEndAddr(const ELF *elf);
extern const Elf64_Shdr *getELFSection(const ELF *elf, const char *name);
extern const Elf64_Sym *getELFDynSym(const ELF *elf, const char *name);
extern const Elf64_Sym *getELFSym(const ELF *elf, const char *name);
extern intptr_t getELFPLTEntry(const ELF *elf, const char *name);
extern intptr_t getELFGOTEntry(const ELF *elf, const char *name);
extern const char *getELFStrTab(const ELF *elf);
extern const SectionInfo &getELFSectionInfo(const ELF *elf);
extern const SymbolInfo &getELFDynSymInfo(const ELF *elf);
extern const SymbolInfo &getELFSymInfo(const ELF *elf);
extern const GOTInfo &getELFGOTInfo(const ELF *elf);
extern const PLTInfo &getELFPLTInfo(const ELF *elf);
extern intptr_t getELFObject(const ELF *elf, const char *name,
    bool end = false);

// Note: Windows PE files are parsed as "pseudo-ELF" files.

/*
 * Misc. functions:
 */
extern const Call &makeCall(const ELF *elf, const char *filename,
    const char *entry, CallABI abi, CallJump jmp, PatchPos pos,
    const std::vector<Argument> &args);
extern void getInstrInfo(const ELF *elf, const Instr *I, InstrInfo *info,
    void *raw = nullptr);
extern const char *getRegName(Register r);
extern ssize_t findInstr(const Instr *Is, size_t size, intptr_t address);
extern const BB *findBB(const BBs &bbs, size_t idx);
extern const F *findF(const Fs &fs, size_t idx);
extern const Line *findLine(const Lines &Ls, intptr_t address);
extern void buildTargets(const ELF *elf, const Instr *Is, size_t size,
    Targets &targets);
extern void buildBBs(const ELF *elf, const Instr *Is, size_t size,
    const Targets &targets, BBs &bbs);
extern void buildFs(const ELF *elf, const Instr *Is, size_t size,
    const Targets &targets, Fs &fs);
extern void buildLines(const ELF *elf, const Instr *Is, size_t size,
    Lines &Ls);
extern intptr_t getSymbol(const ELF *elf, const char *symbol);
extern void NO_RETURN error(const char *msg, ...);
extern void warning(const char *msg, ...);
extern void debug(const char *msg, ...);

}   // namespace e9tool

#endif
